A comprehensive guide for web developers and designers on using CSS font-feature-settings to control advanced OpenType typography features like ligatures, kerning, and stylistic sets.
Unlocking Typographic Power: A Deep Dive into CSS Font Feature Values and OpenType
In the world of web design, typography is often the unsung hero of user experience. We meticulously choose font families, weights, and sizes to craft a clear and aesthetically pleasing interface. But what if we could go deeper? What if the font files we use every day held secrets to richer, more expressive, and more professional typography? The truth is, they do. These secrets are called OpenType features, and CSS provides us with the keys to unlock them.
For too long, the nuanced control enjoyed by print designers—things like true small caps, elegant discretionary ligatures, and context-aware numeral styles—seemed out of reach for the web. Today, that is no longer the case. This comprehensive guide will take you on a journey into the world of CSS font feature values, exploring how you can harness the full power of your web fonts to create truly sophisticated and readable digital experiences.
What Exactly Are OpenType Features?
Before we dive into the CSS, it's crucial to understand what we're controlling. OpenType is a font format that can contain a vast amount of data beyond the basic shapes of letters, numbers, and symbols. Within this data, font designers can embed a wide range of optional capabilities called "features".
Think of these features as built-in instructions or alternate character designs (glyphs) that can be programmatically turned on or off. They are not hacks or browser tricks; they are intentional design choices made by the typographer who created the font. When you activate an OpenType feature, you are asking the browser to use a specific part of the font's design that is intended for a particular purpose.
These features can range from the purely functional, like improving readability with better spacing, to the purely aesthetic, like adding a decorative flourish to a headline.
The CSS Gateway: High-Level Properties and Low-Level Control
CSS provides two primary ways to access OpenType features. The modern, preferred approach is to use a set of high-level, semantic properties. However, there is also a low-level, powerful "catch-all" property for when you need maximum control.
The Preferred Method: High-Level Properties
Modern CSS offers a suite of properties under the `font-variant` umbrella, along with `font-kerning`. These are considered best practice because their names clearly describe their purpose, making your code more readable and maintainable.
- font-kerning: Controls the use of kerning information stored in the font.
- font-variant-ligatures: Controls common, discretionary, historical, and contextual ligatures.
- font-variant-numeric: Controls different styles for figures, fractions, and the slashed zero.
- font-variant-caps: Controls capital letter variations, such as small caps.
- font-variant-alternates: Provides access to stylistic alternates and character variants.
The main advantage of these properties is that you tell the browser what you want to achieve (e.g., `font-variant-caps: small-caps;`), and the browser figures out the best way to do it. If a specific feature isn't available, the browser can handle it gracefully.
The Power Tool: `font-feature-settings`
While high-level properties are great, they don't cover every single OpenType feature available. For complete control, we have the low-level `font-feature-settings` property. It's often described as a tool of last resort, but it's an incredibly powerful one.
The syntax looks like this:
font-feature-settings: "
- Feature Tag: A case-sensitive, four-character string that identifies a specific OpenType feature (e.g., `"liga"`, `"smcp"`, `"ss01"`).
- Value: Typically an integer. For many features, `1` means "on" and `0` means "off". Some features, like stylistic sets, can accept other integer values to select a specific variant.
Golden Rule: Always try to use the high-level `font-variant-*` properties first. If a feature you need isn't accessible through them, or if you need to combine features in a way the high-level properties don't allow, then reach for `font-feature-settings`.
A Practical Tour of Common OpenType Features
Let's explore some of the most useful and interesting OpenType features you can control with CSS. For each, we'll cover its purpose, its 4-character tag, and the CSS to enable it.
Category 1: Ligatures - Connecting Characters Gracefully
Ligatures are special glyphs that combine two or more characters into a single, more harmonious shape. They are essential for preventing awkward character collisions and improving the flow of text.
Standard Ligatures
- Tag: `liga`
- Purpose: To replace common, problematic character combinations like `fi`, `fl`, `ff`, `ffi`, and `ffl` with a single, specially designed glyph. This is a fundamental feature for readability in many fonts.
- High-Level CSS: `font-variant-ligatures: common-ligatures;` (often on by default in browsers)
- Low-Level CSS: `font-feature-settings: "liga" 1;`
Discretionary Ligatures
- Tag: `dlig`
- Purpose: These are more ornamental and stylistic ligatures, such as for combinations like `ct`, `st`, or `sp`. They are not essential for readability and should be used selectively, often in headings or logos, to add a touch of elegance.
- High-Level CSS: `font-variant-ligatures: discretionary-ligatures;`
- Low-Level CSS: `font-feature-settings: "dlig" 1;`
Category 2: Numerals - The Right Number for the Job
Not all numbers are created equal. A good font provides different styles of numerals for different contexts, and controlling them is a hallmark of professional typography.
Oldstyle vs. Lining Figures
- Tags: `onum` (Oldstyle), `lnum` (Lining)
- Purpose: Lining figures are the standard numbers we see everywhere—all uniform in height, aligning with the capital letters. They are perfect for tables, charts, and user interfaces where numbers need to align vertically. Oldstyle figures, by contrast, have varying heights with ascenders and descenders, much like lowercase letters. This allows them to blend seamlessly into a paragraph of text without shouting for attention.
- High-Level CSS: `font-variant-numeric: oldstyle-nums;` or `font-variant-numeric: lining-nums;`
- Low-Level CSS: `font-feature-settings: "onum" 1;` or `font-feature-settings: "lnum" 1;`
Proportional vs. Tabular Figures
- Tags: `pnum` (Proportional), `tnum` (Tabular)
- Purpose: This controls the width of the numbers. Tabular figures are monospaced—each number takes up the exact same horizontal space. This is critical for financial reports, code, or any data table where numbers in different rows must align perfectly in columns. Proportional figures have variable widths; for example, the number '1' takes up less space than the number '8'. This creates more even spacing and is ideal for use in running text.
- High-Level CSS: `font-variant-numeric: proportional-nums;` or `font-variant-numeric: tabular-nums;`
- Low-Level CSS: `font-feature-settings: "pnum" 1;` or `font-feature-settings: "tnum" 1;`
Fractions and Slashed Zero
- Tags: `frac` (Fractions), `zero` (Slashed Zero)
- Purpose: The `frac` feature beautifully formats text like `1/2` into a true diagonal fraction glyph (½). The `zero` feature replaces the standard '0' with a version that has a slash or a dot through it to clearly distinguish it from the capital letter 'O', which is vital in technical documentation, serial numbers, and code.
- High-Level CSS: `font-variant-numeric: diagonal-fractions;` and `font-variant-numeric: slashed-zero;`
- Low-Level CSS: `font-feature-settings: "frac" 1, "zero" 1;`
Category 3: Kerning - The Art of Spacing
Kerning
- Tag: `kern`
- Purpose: Kerning is the process of adjusting the space between individual pairs of letters to improve visual appeal and readability. For example, in the combination "AV", the V is tucked slightly under the A. Most quality fonts contain hundreds or thousands of these kerning pairs. While it's almost always enabled by default, you can control it.
- High-Level CSS: `font-kerning: normal;` (default) or `font-kerning: none;`
- Low-Level CSS: `font-feature-settings: "kern" 1;` (on) or `font-feature-settings: "kern" 0;` (off)
Category 4: Case Variations - Beyond Uppercase and Lowercase
Small Caps
- Tags: `smcp` (from lowercase), `c2sc` (from uppercase)
- Purpose: This feature enables true small caps, which are specifically designed glyphs that are the height of lowercase letters but have the form of uppercase letters. They are far superior to the "fake" small caps created by simply scaling down full-size capitals. Use them for acronyms, subheadings, or emphasis.
- High-Level CSS: `font-variant-caps: small-caps;`
- Low-Level CSS: `font-feature-settings: "smcp" 1;`
Category 5: Stylistic Alternates - The Designer's Touch
This is where typography gets truly expressive. Many fonts come with alternate versions of characters that you can swap in to change the tone or style of the text.
Stylistic Sets
- Tags: `ss01` through `ss20`
- Purpose: This is one of the most exciting features, but it's only accessible via `font-feature-settings`. A font designer can group related stylistic alternates into sets. For example, `ss01` might activate a single-story 'a', `ss02` might change the tail on the 'y', and `ss03` might provide a more geometric set of punctuation. The possibilities are entirely up to the font designer.
- Low-Level CSS: `font-feature-settings: "ss01" 1;` or `font-feature-settings: "ss01" 1, "ss05" 1;`
Swashes
- Tag: `swsh`
- Purpose: Swashes are decorative, flamboyant flourishes added to characters, often at the beginning or end of a word. They are common in script and display fonts and should be used very sparingly for maximum impact, such as for a drop cap or a single word in a logo.
- Low-Level CSS: `font-feature-settings: "swsh" 1;`
How to Discover Available Features in a Font
This is all wonderful, but how do you know which features your chosen font actually supports? A feature will only work if the font designer built it into the font file. Here are a few ways to find out:
- Font Service Specimen Pages: Most reputable font foundries and services (like Adobe Fonts, Google Fonts, and commercial type foundries) will list and demonstrate the supported OpenType features on the font's main page. This is usually the easiest place to start.
- Browser Developer Tools: Modern browsers have amazing tools for this. In Chrome or Firefox, inspect an element, go to the "Computed" tab, and scroll all the way down. You'll find a "Rendered Fonts" section that tells you which font file is being used. In Firefox, there's a dedicated "Fonts" tab that will explicitly list every available OpenType feature tag for the selected element's font. This is an incredibly powerful way to explore a font's capabilities live.
- Desktop Font Analysis Tools: For locally installed font files (`.otf`, `.ttf`), you can use specialized applications or websites (like wakamaifondue.com) that analyze a font file and give you a detailed report of all its features, supported languages, and glyphs.
Performance and Browser Support
Two common concerns are performance and browser compatibility. The good news is that both are excellent.
- Browser Support: The `font-feature-settings` property has been widely supported in all major browsers for many years. The newer `font-variant-*` properties also have excellent support across the board. You can use them with confidence.
- Performance: Activating OpenType features has a negligible impact on rendering performance. The logic and alternate glyphs are already in the font file that has been downloaded; you are simply telling the browser's rendering engine which instructions to follow. The performance cost is in the font file's size itself, not in using the features it contains. A font with many features might be a larger file, but activating them is essentially free.
Best Practices and Actionable Insights
With great power comes great responsibility. Here's how to use font features effectively and professionally.
1. Use Features for Progressive Enhancement
Think of OpenType features as an enhancement. Your text must be perfectly readable and functional without them. Activating oldstyle numerals or discretionary ligatures simply elevates the typographic quality for users on modern browsers, creating a better, more polished experience.
2. Context is Everything
Don't apply features globally without thought. Apply the right feature in the right place.
- Use oldstyle proportional numerals for body paragraphs.
- Use lining tabular numerals for data tables and price lists.
- Use discretionary ligatures and swashes for display headings, not body text.
- Use small caps for acronyms or labels to help them blend in.
3. Organize with CSS Custom Properties
To keep your code clean and maintainable, define your feature combinations in CSS Custom Properties (variables). This makes it easy to apply them consistently and update them from one central location.
Example:
:root {
--font-features-body: "liga" 1, "onum" 1, "pnum" 1, "kern" 1;
--font-features-heading: "liga" 1, "dlig" 1, "lnum" 1;
--font-features-data: "lnum" 1, "tnum" 1, "zero" 1;
}
body {
font-feature-settings: var(--font-features-body);
}
h1, h2, h3 {
font-feature-settings: var(--font-features-heading);
}
.price, .code, .table-cell {
font-feature-settings: var(--font-features-data);
}
4. Subtlety is Key
The best typography is often invisible. The goal is to improve readability and aesthetics without drawing attention to the technique itself. Avoid the temptation to turn on every available feature. A few well-chosen features applied in the right context will have a far greater impact than a chaotic mix of everything.
Conclusion: The New Frontier of Web Typography
Mastering CSS font feature values is a transformative step for any web developer or designer. It moves us beyond the basic mechanics of setting font sizes and weights and into the realm of true digital typography. By understanding and utilizing the rich features embedded within our fonts, we can close the long-standing gap between print and web design, creating digital experiences that are not only functional and accessible but also typographically beautiful and sophisticated.
So, the next time you choose a font for a project, don't stop there. Dive into its documentation, inspect it with your browser's developer tools, and discover the hidden power it holds. Experiment with ligatures, numerals, and stylistic sets. Your attention to these details will set your work apart and contribute to a more refined and readable web for everyone.